# 设计模式

在软件工程中,设计模式 (opens new window)是对软件设计中普遍存在的各种问题,所提出的解决方案。

# 一、行为型

行为型模式 (opens new window)为设计模式的一种类型,用来识别对象之间的常用交流模式并加以实现。

# 中介者模式

中介者模式 (opens new window)定义了一个中介者对象,该对象封装了系统中对象间的交互方式,能减少对象之间混乱无序的依赖关系。

该模式会限制对象之间的直接交互,迫使它们通过一个中介者对象进行合作。

# 用户间通信

在没有使用中介者模式的情况下,多个类对象之间需要直接通信。

例如,一个聊天室中有多个用户,用户之间直接发送消息。

class User:
    def __init__(self, name):
        self.name = name

    def send_message(self, message, to_user):
        print(f"{self.name} 发送消息给 {to_user.name}: {message}")

# 创建用户对象
user1 = User("Alice")
user2 = User("Bob")

# 用户直接通信
user1.send_message("Hello, Bob!", user2)
user2.send_message("Hi, Alice!", user1)

在这个例子中,用户 AliceBob 之间直接通信。

这意味着如果有更多的用户加入,他们之间的依赖性会增加,通信逻辑也会变得复杂。

使用中介者模式,我们会引入一个中介者对象(例如聊天室)来管理用户之间的消息传递,用户只需与中介者通信,而无需关心其他用户的存在。

# 定义中介者
class ChatRoom:
    def show_message(self, user, message):
        print(f"{user.name} 发送消息: {message}")

# 修改后的用户类
class User:
    def __init__(self, name, chat_room):
        self.name = name
        self.chat_room = chat_room

    def send_message(self, message):
        self.chat_room.show_message(self, message)

# 创建中介者对象
chat_room = ChatRoom()

# 创建用户对象
user1 = User("Alice", chat_room)
user2 = User("Bob", chat_room)

# 用户通过中介者通信
user1.send_message("Hello, Bob!")
user2.send_message("Hi, Alice!")

# 请求处理

假设有一个 Ping 请求和一个 PingHandler 来处理这个请求。

在没有中介者模式的情况下,Ping 请求会直接与 PingHandler 交互。

class Ping:
    def __init__(self, handler):
        self.handler = handler

    def send_request(self):
        print("Ping: Sending request...")
        self.handler.handle()

class PingHandler:
    def handle(self):
        print("PingHandler: Handling the ping request...")

# 直接创建对象并发送请求
handler = PingHandler()
ping = Ping(handler)
ping.send_request()

在这个例子中,Ping 请求类直接依赖于 PingHandler 类。

如果我们以后想要改变处理逻辑或增加其他处理器,就需要修改 Ping 类,这破坏了代码的可扩展性和可维护性。

现在我们引入一个中介者来管理 Ping 请求和 PingHandler 的交互。

Ping 对象与 PingHandler 通过 Mediator 中介者进行交互,Ping 对象只知道 Mediator,不需要直接依赖 PingHandler

这样,当需要更改处理逻辑或添加新功能时,只需修改或扩展 Mediator,而不需要更改 Ping 类本身。

class PingHandler:
    def handle(self):
        print("PingHandler: Handling the ping request...")

class Mediator:
    def __init__(self):
        self.handler = PingHandler()

    def notify(self, sender, event):
        if event == "PingRequest":
            self.handler.handle()

class Ping:
    def __init__(self, mediator):
        self.mediator = mediator

    def send_request(self):
        print("Ping: Sending request...")
        self.mediator.notify(self, "PingRequest")

# 使用中介者进行通信
mediator = Mediator()
ping = Ping(mediator)
ping.send_request()

# 策略模式

策略模式 (opens new window)是一种行为设计模式,它能让你定义一系列算法,并将每种算法分别放入独立的类中,以使算法的对象能够相互替换。

当你想使用对象中各种不同的算法变体,并希望能在运行时切换算法时,可使用策略模式。

# 支付方式

假设我们有一个电子商务系统,用户可以使用不同的支付方式完成购买,比如使用 CreditCard 或 PayPal。

最初,我们可能会直接在代码中处理不同的支付方式,但随着支付方式的增加,代码会变得越来越难以维护。

class PaymentProcessor:
    def process_payment(self, payment_type, amount):
        if payment_type == "CreditCard":
            self._process_credit_card_payment(amount)
        elif payment_type == "PayPal":
            self._process_paypal_payment(amount)
        else:
            raise ValueError("Unsupported payment type")

    def _process_credit_card_payment(self, amount):
        print(f"Processing credit card payment of ${amount}")

    def _process_paypal_payment(self, amount):
        print(f"Processing PayPal payment of ${amount}")

# 使用示例
processor = PaymentProcessor()
processor.process_payment("CreditCard", 100)
processor.process_payment("PayPal", 150)

我们可以使用策略模式来解耦支付逻辑,使得系统更易扩展。

我们将创建一个接口来表示支付策略,并为每种支付方式创建一个实现该接口的类。

from abc import ABC, abstractmethod

# 定义支付策略接口
class PaymentStrategy(ABC):
    @abstractmethod
    def pay(self, amount):
        pass

# 实现信用卡支付策略
class CreditCardPayment(PaymentStrategy):
    def pay(self, amount):
        print(f"Processing credit card payment of ${amount}")

# 实现 PayPal 支付策略
class PayPalPayment(PaymentStrategy):
    def pay(self, amount):
        print(f"Processing PayPal payment of ${amount}")

# 支付处理类只需要接受一个策略接口
class PaymentProcessor:
    def __init__(self, strategy: PaymentStrategy):
        self.strategy = strategy

    def process_payment(self, amount):
        self.strategy.pay(amount)

# 使用不同的支付策略
credit_card_payment = CreditCardPayment()
paypal_payment = PayPalPayment()

processor = PaymentProcessor(credit_card_payment)
processor.process_payment(100)

processor = PaymentProcessor(paypal_payment)
processor.process_payment(150)

# 二、创建型

创建型模式 (opens new window)是处理对象创建的设计模式,试图根据实际情况使用合适的方式创建对象,因为基本的对象创建方式可能会导致设计上的问题,或增加设计的复杂度。

# 单例模式

单例模式 (opens new window)是一种创建型设计模式,让你能够保证一个类只有一个实例,并提供一个访问该实例的全局节点。

# 支付策略

确保每种支付策略都只有一个实例,可以使用单例模式来实现。

public interface IPaymentStrategy
{
    void ProcessPayment();
}

public class CreditCardPayment : IPaymentStrategy
{
    private static readonly CreditCardPayment _instance = new CreditCardPayment();
    private CreditCardPayment() { }

    public static CreditCardPayment Instance => _instance;

    public void ProcessPayment()
    {
        Console.WriteLine("Processing credit card payment...");
    }
}

# Reference